﻿// Inner Fire 游戏引擎库
// DxInstancedSprite 渲染器实例精灵绘制
//
// Copyright (c) 2025 by 尔西大帝. All rights reserved.
//
// 用于DirectX的渲染器。
// 此文件分装用于实例精灵绘制，调试线段绘制等。
//
// Author: 尔西大帝
// Email: 2670613871@qq.com
// Created: 2025-05-21

#pragma once

#include "dx_module.h"
#include <EASTL/vector.h>
#include <dx/core/dx_core.h>
#include <dx/core/upload_buffer.h>
#include <dx/mesh/dx_mesh.h>
#include <dx/mesh/instanced_sprites.h>
#include <dx/mesh/map_blocks.h>

namespace ifire::dx {
class DxGraphics;

class DxInstancedSprite : public DxModule {
public:
  DxInstancedSprite(DxGraphics* dx);
  DxInstancedSprite(const DxInstancedSprite& rhs) = delete;
  DxInstancedSprite& operator=(const DxInstancedSprite& rhs) = delete;
  ~DxInstancedSprite() = default;

  // 每帧检查的更新
  void Update();

  // 创建一个Pool，并且在帧资源中进行相应的初始化
  InstancedSprites* Create(
      InstancedSpriteType type, DxMesh* mesh, size_t count);
  // 创建一个地图项目。其中只有核心项需要在帧资源，结构化缓冲区不需要更新。
  MapBlocks* CreateMapBlocks(DxMesh* mesh, ikit::sstr sub_name, size_t count);

  // 进行绘制
  void Draw(ID3D12GraphicsCommandList* cmd);

  // ------
  // 属性访问
  // ------
  eastl::vector<InstancedSpritesPtr>& Sprites() { return instanced_sprites_; }

private:
  // 仅对一个类型进行绘制
  void DrawTypeGroups(ID3D12GraphicsCommandList* cmd,
      UploadBuffer<InstancedSpriteConstants>* cb, InstancedSpriteType type,
      const char* pipeline);
  // 绘制一个项目
  void DrawItem(ID3D12GraphicsCommandList* cmd,
      UploadBuffer<InstancedSpriteConstants>* cb, InstancedSprites* item);
  // 仅对一个类型进行绘制(地图）。目前地图没有分类型，但以后肯定会有的。
  void DrawMapBlocks(ID3D12GraphicsCommandList* cmd,
      UploadBuffer<InstancedSpriteConstants>* cb, const char* pipeline);
  // 绘制一个地图项目
  void DrawMapBlock(ID3D12GraphicsCommandList* cmd,
      UploadBuffer<InstancedSpriteConstants>* cb, MapBlocks* item);

  eastl::vector<InstancedSpritesPtr> instanced_sprites_;
  eastl::vector<MapBlocksPtr> map_blocks_;
};

} // namespace ifire::dx